﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Infrastructure.Notification;
using Tecnosop.WebUI.Models;
using System.Data;
using Rotativa;
using System.Web.UI;

namespace Tecnosop.WebUI.Controllers
{
    public partial class FacturaVentaDirectaController : Controller
    {
        private Entidades db = new Entidades();

        #region CRUD

        [Authorize]
        public virtual ActionResult Index()
        {
            //FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(3, "Comercializadora Tecnosop");
            //return RedirectToAction(Actions.printPdfVentaDirecta(5, "Comercializadora Tecnosop"));
            return View();
        }

        public virtual ActionResult printPdfVentaDirecta(int idF, string RazonSocialF)
        {
            //return View();
            return new ActionAsPdf("VistaBlancaVentaDirecta", new { id = idF, RazonSocial = RazonSocialF }) { FileName = "Factura-venta-directa.pdf" };
        }

        public virtual ActionResult VistaBlancaVentaDirecta(int id, string RazonSocial)
        {
            FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(id, RazonSocial);
            //factura.FACTURA_EMITIDA=true //hay que definir que valor se va a usar
            db.Entry(factura).State = EntityState.Modified;
            //db.CLIENTE.Remove(cliente);
            db.SaveChanges();
            Func<ITEM, string> GetTipo = Item =>
            {
                return Item != null ?
                    Item.EQUIPO != null ?
                        Item.EQUIPO.TIPO_EQUIPO :
                        Item.INSUMO != null ?
                            Item.INSUMO.TIPO_INSUMO : ""
                    : "";
            };


            List<DetalleFacturaVentaDirectaViewModel> DetalleFactura = new List<DetalleFacturaVentaDirectaViewModel>();

            foreach (var detalle in factura.DETALLE_FACTURA_VENTA_DIRECTA)
            {
                ITEM item = db.ITEM.Find(detalle.CODIGO_ITEM);

                DetalleFacturaVentaDirectaViewModel Det = new DetalleFacturaVentaDirectaViewModel
                {
                    NUMERO_LINEA_DETALLE = detalle.DETALLE_VENTA_DIRECTA,
                    CODIGO_ITEM = detalle.CODIGO_ITEM,
                    NUMERO_FACTURA = detalle.NUMERO_FACTURA,
                    RAZON_SOCIAL = detalle.RAZON_SOCIAL,
                    CANTIDAD = detalle.CANTIDAD ?? 1,
                    SUBTOTAL = detalle.SUBTOTAL ?? 0,
                    GARANTIA = detalle.GARANTIA,
                    PRECIO = detalle.PRECIO_DETALLE// != null ? detalle.PRECIO_DETALLE.Value : GetPrecio(item)
                };

                Det.setDescripcion(GetTipo(item), item.MARCA, item.MODELO);

                DetalleFactura.Add(Det);
            }

            if (!(factura.FACTURA.FACTURA_EMITIDA ?? false))
            {
                factura.FACTURA.FACTURA_EMITIDA = true;
                db.Entry(factura).State = System.Data.EntityState.Modified;
                db.SaveChanges();
            }

            return View(new FacturaVentaDirectaViewModel
            {
                NUMERO_FACTURA = factura.NUMERO_FACTURA,
                RAZON_SOCIAL = factura.RAZON_SOCIAL,
                RUT_CLIENTE = factura.RUT_CLIENTE,
                CLIENTE = factura.CLIENTE,
                FACTURA = factura.FACTURA,
                TOTAL = factura.FACTURA.TOTAL ?? 0,
                DETALLE_FACTURA = DetalleFactura
            });
        }

        [Authorize]
        public virtual ActionResult Details(int id, string RazonSocial)
        {
            FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(id, RazonSocial);

            Func<ITEM, string> GetTipo = Item =>
            {
                return Item != null ?
                    Item.EQUIPO != null ?
                        Item.EQUIPO.TIPO_EQUIPO :
                        Item.INSUMO != null ?
                            Item.INSUMO.TIPO_INSUMO : ""
                    : "";
            };

            List<DetalleFacturaVentaDirectaViewModel> DetalleFactura = new List<DetalleFacturaVentaDirectaViewModel>();

            foreach (var detalle in factura.DETALLE_FACTURA_VENTA_DIRECTA)
            {
                ITEM item = db.ITEM.Find(detalle.CODIGO_ITEM);

                DetalleFacturaVentaDirectaViewModel Det = new DetalleFacturaVentaDirectaViewModel
                {
                    NUMERO_LINEA_DETALLE = detalle.DETALLE_VENTA_DIRECTA,
                    CODIGO_ITEM = detalle.CODIGO_ITEM,
                    NUMERO_FACTURA = detalle.NUMERO_FACTURA,
                    RAZON_SOCIAL = detalle.RAZON_SOCIAL,
                    GARANTIA = detalle.GARANTIA,
                    CANTIDAD = detalle.CANTIDAD ?? 1,
                    SUBTOTAL = detalle.SUBTOTAL ?? 0,
                    PRECIO = detalle.PRECIO_DETALLE//.HasValue ? detalle.PRECIO_DETALLE.Value : item.PRECIO
                };

                Det.setDescripcion(GetTipo(item), item.MARCA, item.MODELO);

                DetalleFactura.Add(Det);
            }

            if (factura.FACTURA.FACTURA_EMITIDA ?? false)
            {
                return View("DetalleFacturaEmitida", new FacturaVentaDirectaViewModel
                {
                    NUMERO_FACTURA = factura.NUMERO_FACTURA,
                    RAZON_SOCIAL = factura.RAZON_SOCIAL,
                    RUT_CLIENTE = factura.RUT_CLIENTE,
                    CLIENTE = factura.CLIENTE,
                    FACTURA = factura.FACTURA,
                    TOTAL = factura.FACTURA.TOTAL ?? 0,
                    DETALLE_FACTURA = DetalleFactura
                });
            }
            else
            {
                this.ShowMessage(MessageType.Warning, "Confirme que los precios de los equipos e insumos estén actualizados antes de agregarlos a la factura");

                return View(new FacturaVentaDirectaViewModel
                {
                    NUMERO_FACTURA = factura.NUMERO_FACTURA,
                    RAZON_SOCIAL = factura.RAZON_SOCIAL,
                    RUT_CLIENTE = factura.RUT_CLIENTE,
                    CLIENTE = factura.CLIENTE,
                    FACTURA = factura.FACTURA,
                    TOTAL = factura.FACTURA.TOTAL ?? 0,
                    DETALLE_FACTURA = DetalleFactura
                });
            }
        }

        [Authorize]
        public virtual ActionResult Create(int id, bool razon, string RutCliente)
        {
            string RazonSocial = razon ? "Comercializadora Tecnosop" : "Juan Carlos Maldonado Huerta";
            FACTURA factura = db.FACTURA.Find(id, RazonSocial);
            CLIENTE cliente = db.CLIENTE.Find(RutCliente);

            if (factura == null || cliente == null)
            {
                return RedirectToAction(MVC.Facturas.Create(error: true));
            }
            else
            {
                if (db.FACTURA_VENTA_DIRECTA.Find(id, RazonSocial) != null)
                {
                    return RedirectToAction(Actions.Details(id, RazonSocial));
                }
                else
                {
                    FACTURA_VENTA_DIRECTA facturaVentaDirecta = new FACTURA_VENTA_DIRECTA
                    {
                        NUMERO_FACTURA = factura.NUMERO_FACTURA,
                        RAZON_SOCIAL = factura.RAZON_SOCIAL,
                        RUT_CLIENTE = cliente.RUT_CLIENTE,
                    };

                    db.FACTURA_VENTA_DIRECTA.Add(facturaVentaDirecta);
                    db.SaveChanges();

                    //facturaVentaDirecta.FACTURA.TOTAL = 0;
                    //db.Entry(facturaVentaDirecta).State = System.Data.EntityState.Modified;
                    //db.SaveChanges();

                    return RedirectToAction(Actions.Details(id, RazonSocial));
                }
            }
        }

        [Authorize]
        public virtual ActionResult Edit(int id, string RazonSocial)
        {
            return View(db.FACTURA_VENTA_DIRECTA.Find(id, RazonSocial));
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Edit(EditFacturaVentaDirectaViewModel facturaVM)
        {
            if (ModelState.IsValid)
            {
                FACTURA factura = db.FACTURA.Find(facturaVM.id, facturaVM.RazonSocial);

                factura.FECHA_INSTALACION = facturaVM.Factura.FECHA_INSTALACION;
                factura.COND_DE_VENTA = facturaVM.Factura.COND_DE_VENTA;

                db.Entry(factura).State = System.Data.EntityState.Modified;
                db.SaveChanges();

                this.ShowMessage(MessageType.Success, "Se guardaron los cambios correctamente.");
                return RedirectToAction(Actions.Details(factura.NUMERO_FACTURA, factura.RAZON_SOCIAL));
            }
            else
            {
                this.ShowMessage(MessageType.Error, "Ocurrió un error al guardar los cambios.");
                return View();
            }
            //try
            //{
            //    // TODO: Add update logic here

            //    return RedirectToAction("Index");
            //}
            //catch
            //{
            //    return View();
            //}
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Delete(int id, string RazonSocial)
        {
            try
            {
                FACTURA factura = db.FACTURA.Find(id, RazonSocial);

                db.FACTURA_VENTA_DIRECTA.Remove(factura.FACTURA_VENTA_DIRECTA);
                db.SaveChanges();

                db.FACTURA.Remove(factura);
                db.SaveChanges();

                this.ShowMessage(MessageType.Success, "Se eliminó la factura N°: " + id + " de la base de datos.");
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "No se pudo eliminar la factura N°: " + id + " de la base de datos.");
            }

            return RedirectToAction(MVC.Facturas.Index());
        }

        #endregion

        #region "Grid Detalle"

        [HttpPost]
        [Authorize]
        public virtual ActionResult GridAddDetalleFactura(int NUMERO_FACTURA, string RAZON_SOCIAL)
        {
            DetalleFacturaVentaDirectaViewModel detalleVM = new DetalleFacturaVentaDirectaViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                    //ITEM item = db.ITEM.Find(detalleVM.CODIGO_ITEM);
                    FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(NUMERO_FACTURA, RAZON_SOCIAL);

                    int precio_item = db.ITEM.Find(detalleVM.CODIGO_ITEM).PRECIO.Value;
                    DETALLE_FACTURA_VENTA_DIRECTA detalle = new DETALLE_FACTURA_VENTA_DIRECTA
                    {
                        CODIGO_ITEM = detalleVM.CODIGO_ITEM,
                        NUMERO_FACTURA = detalleVM.NUMERO_FACTURA,
                        RAZON_SOCIAL = detalleVM.RAZON_SOCIAL,
                        GARANTIA = detalleVM.GARANTIA,
                        CANTIDAD = detalleVM.CANTIDAD,
                        PRECIO_DETALLE = detalleVM.PRECIO != null ? detalleVM.PRECIO.Value : precio_item,
                        SUBTOTAL = detalleVM.CANTIDAD * (detalleVM.PRECIO != null ? detalleVM.PRECIO.Value : precio_item)
                    };

                    factura.DETALLE_FACTURA_VENTA_DIRECTA.Add(detalle);
                    db.SaveChanges();

                    factura.FACTURA.TOTAL += detalle.SUBTOTAL;
                    db.Entry(factura).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se agregó correctamente la línea de detalle");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de agregar la línea de detalle");
                }
            }

            return RedirectToAction(Actions.Details(NUMERO_FACTURA, RAZON_SOCIAL));
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult GridEditDetalleFactura(int NUMERO_FACTURA, string RAZON_SOCIAL)
        {
            DetalleFacturaVentaDirectaViewModel detalleVM = new DetalleFacturaVentaDirectaViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                    FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(NUMERO_FACTURA, RAZON_SOCIAL);
                    var detalle = factura.DETALLE_FACTURA_VENTA_DIRECTA.Single(d => d.DETALLE_VENTA_DIRECTA == detalleVM.NUMERO_LINEA_DETALLE);

                    int codigo_item_inicial = detalle.CODIGO_ITEM;
                    int cantidad_inicial = detalle.CANTIDAD.Value;
                    int precio_item_detalle = detalleVM.PRECIO != null ? detalleVM.PRECIO.Value : db.ITEM.Find(detalleVM.CODIGO_ITEM).PRECIO.Value;
                    int subtotal_inicial = detalle.SUBTOTAL.Value;

                    detalle.CODIGO_ITEM = detalleVM.CODIGO_ITEM;
                    detalle.CANTIDAD = detalleVM.CANTIDAD;
                    detalle.GARANTIA = detalleVM.GARANTIA;
                    detalle.PRECIO_DETALLE = precio_item_detalle;
                    detalle.SUBTOTAL = detalleVM.CANTIDAD * precio_item_detalle;

                    db.Entry(detalle).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    factura.FACTURA.TOTAL -= subtotal_inicial;
                    factura.FACTURA.TOTAL += detalle.SUBTOTAL;

                    db.Entry(factura).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se guardaron los cambios correctamente");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de editar la línea de detalle");
                }
            }

            return RedirectToAction(Actions.Details(NUMERO_FACTURA, RAZON_SOCIAL));
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult GridDeleteDetalleFactura(int NUMERO_FACTURA, string RAZON_SOCIAL)
        {
            DetalleFacturaVentaDirectaViewModel detalleVM = new DetalleFacturaVentaDirectaViewModel();

            if (TryUpdateModel(detalleVM))
            {
                try
                {
                    FACTURA_VENTA_DIRECTA factura = db.FACTURA_VENTA_DIRECTA.Find(NUMERO_FACTURA, RAZON_SOCIAL);
                    var detalle = factura.DETALLE_FACTURA_VENTA_DIRECTA.Single(d => d.DETALLE_VENTA_DIRECTA == detalleVM.NUMERO_LINEA_DETALLE);

                    int subtotal_inicial = detalle.SUBTOTAL.Value;

                    factura.DETALLE_FACTURA_VENTA_DIRECTA.Remove(detalle);
                    db.SaveChanges();

                    factura.FACTURA.TOTAL -= subtotal_inicial;
                    db.Entry(factura).State = System.Data.EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Se eliminó correctamente la línea de detalle");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un problema al tratar de eliminar la línea de detalle");
                }
            }

            return RedirectToAction(Actions.Details(NUMERO_FACTURA, RAZON_SOCIAL));
        }

        #endregion

        [Authorize]
        public virtual ActionResult CambiarDescuento(int NUMERO_FACTURA, string RAZON_SOCIAL)
        {
            int DESCUENTO = Convert.ToInt32(Request.Form["FACTURA.DESCUENTO"]);
            FACTURA factura = db.FACTURA.Find(NUMERO_FACTURA, RAZON_SOCIAL);

            factura.DESCUENTO = DESCUENTO;
            db.Entry(factura).State = System.Data.EntityState.Modified;
            db.SaveChanges();

            this.ShowMessage(MessageType.Success, "El descuento fue aplicado para esta factura.");

            return RedirectToAction(Actions.Details(NUMERO_FACTURA, RAZON_SOCIAL));
        }

        #region Validaciones

        [Authorize]
        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaNumeroItem(int CODIGO_ITEM)
        {
            return Json(db.ITEM.Any(i => i.CODIGO_ITEM == CODIGO_ITEM), JsonRequestBehavior.AllowGet);
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
